

#import "ColorPickerView.h"
#import "GradientView.h"
#import "Constants.h"
#import "UIColor-HSVAdditions.h"

@implementation ColorPickerView

@synthesize currentHue;
@synthesize currentSaturation;
@synthesize currentBrightness;
@synthesize updateSwatchViewDelegate;
-(void) setUp
{
    txtB.keyboardType= UIKeyboardTypeNumbersAndPunctuation;
    txtB.returnKeyType = UIReturnKeyDone;
    txtB.autocorrectionType = UITextAutocorrectionTypeNo;
    txtB.delegate = self;
    txtB.userInteractionEnabled = YES;
    
    txtR.keyboardType= UIKeyboardTypeNumbersAndPunctuation;
    txtR.returnKeyType = UIReturnKeyDone;
    txtR.autocorrectionType = UITextAutocorrectionTypeNo;
    txtR.delegate = self;
    
    txtG.keyboardType= UIKeyboardTypeNumbersAndPunctuation;
    txtG.returnKeyType = UIReturnKeyDone;
    txtG.autocorrectionType = UITextAutocorrectionTypeNo;
    txtG.delegate = self;
    
    txtHue.keyboardType= UIKeyboardTypeNumbersAndPunctuation;
    txtHue.returnKeyType = UIReturnKeyDone;
    txtHue.autocorrectionType = UITextAutocorrectionTypeNo;
    txtHue.delegate = self;
    
    txtSat.keyboardType= UIKeyboardTypeNumbersAndPunctuation;
    txtSat.returnKeyType = UIReturnKeyDone;
    txtSat.autocorrectionType = UITextAutocorrectionTypeNo;
    txtSat.delegate = self;
    
    txtVal.keyboardType= UIKeyboardTypeNumbersAndPunctuation;
    txtVal.returnKeyType = UIReturnKeyDone;
    txtVal.autocorrectionType = UITextAutocorrectionTypeNo;
    txtVal.delegate = self;
    
    
    txtHex.keyboardType = UIKeyboardTypeASCIICapable;
    txtHex.returnKeyType = UIReturnKeyDone;
    txtHex.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;
    txtHex.delegate = self;
    txtHex.enabled = YES;

    hexCharacterSet =[[NSCharacterSet characterSetWithCharactersInString:@"0123456789ABCDEF"]retain];
    decimalCharacterSet =[[NSCharacterSet characterSetWithCharactersInString:@"0123456789"]retain];
}
-(void) awakeFromNib
{
    [self setUp];
    [txtHex becomeFirstResponder];
}
- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
    }
    return self;
}
-(id) init
{
    self = [super init];
    if (self) {
        //[self setUp];
    }
    return self;
}
- (id)initWithCoder:(NSCoder*)coder  {
    self = [super initWithCoder:coder];
	if (self) {
		gradientView = [[GradientView alloc] initWithFrame:kBrightnessGradientPlacent];
		//[gradientView setTheColor:[UIColor yellowColor]];
		[self addSubview:gradientView];
		[self sendSubviewToBack:gradientView];
		[self setMultipleTouchEnabled:YES];
		colorMatrixFrame = kHueSatFrame;
		UIImageView *hueSatImage = [[UIImageView alloc] initWithFrame:colorMatrixFrame];
		[hueSatImage setImage:[UIImage imageNamed:kHueSatImage]];
		[self addSubview:hueSatImage];
		[self sendSubviewToBack:hueSatImage];
		[hueSatImage release];
		currentBrightness = kInitialBrightness;		
		currentColor = [[UIColor alloc]init];
	}
	return self;
} 
-(void) updateAllTextFieldWithColor:(UIColor*) color
{

        

    txtR.text =  [[NSString alloc] initWithFormat:@"%d", (int)(color.red*255)];
    txtG.text = [[NSString alloc] initWithFormat:@"%d", (int)(color.green*255)];
    txtB.text = [[NSString alloc] initWithFormat:@"%d", (int)(color.blue*255)];
    
    txtHue.text = [[NSString alloc] initWithFormat:@"%d", (int)(currentHue*360.0f) ];
    txtSat.text = [[NSString alloc] initWithFormat:@"%d", (int)(currentSaturation*100.0f)];
    txtVal.text = [[NSString alloc] initWithFormat:@"%d", (int)(currentBrightness*100.0f)];
    txtHex.text = [color hexStringFromColor];
}
-(void) updateSwatchViewWithColor:(UIColor*)color
{
    [updateSwatchViewDelegate updateSwatchViewWithColor:color];
    [self updateAllTextFieldWithColor:color];
}
- (void) setColor:(UIColor *)color {
    currentColor = color;
    currentHue = color.hue;
    currentSaturation = color.saturation;
    currentBrightness = color.brightness;
    CGPoint hueSatPosition;
    CGPoint brightnessPosition;
    hueSatPosition.x = (currentHue*kMatrixWidth)+kXAxisOffset;
    hueSatPosition.y = (1.0-currentSaturation)*kMatrixHeight+kYAxisOffset;
    brightnessPosition.x = (1.0+kBrightnessEpsilon-currentBrightness)*gradientView.frame.size.width;
    
    // Original input brightness code (from down below)
    // currentBrightness = 1.0-(position.x/gradientView.frame.size.width) + kBrightnessEpsilon;
    
    brightnessPosition.y = kBrightBarYCenter;
    [gradientView setTheColor:color];
    [gradientView setupGradient];
    [gradientView setNeedsDisplay];
    //[showColor setBackgroundColor:currentColor];
    //showColor.swatchColor = currentColor;
    [self updateSwatchViewWithColor:currentColor];
    crossHairs.center = hueSatPosition;
    brightnessBar.center = brightnessPosition;
} 


- (void) updateHueSatWithMovement : (CGPoint) position {

	currentHue = (position.x-kXAxisOffset)/kMatrixWidth;
	currentSaturation = 1.0 -  (position.y-kYAxisOffset)/kMatrixHeight;
	
	UIColor *forGradient = [UIColor colorWithHue:currentHue 
									saturation:currentSaturation 
									brightness: kInitialBrightness 
									alpha:1.0];
	
	[gradientView setTheColor:forGradient];
	[gradientView setupGradient];
	[gradientView setNeedsDisplay];

	currentColor  = [UIColor colorWithHue:currentHue 
									   saturation:currentSaturation 
									   brightness:currentBrightness
									   alpha:1.0];
	
	//[showColor setBackgroundColor:currentColor];
    //showColor.swatchColor = currentColor;
    [self updateSwatchViewWithColor:currentColor];
    //[showColor setNeedsDisplay];
}


- (void) updateBrightnessWithMovement : (CGPoint) position {
	
	currentBrightness = 1.0-(position.x/gradientView.frame.size.width) + kBrightnessEpsilon;
	
	UIColor *forColorView  = [UIColor colorWithHue:currentHue 
										saturation:currentSaturation 
										brightness:currentBrightness
											 alpha:1.0];
	
	//[showColor setBackgroundColor:forColorView];
    //showColor.swatchColor = forColorView;
    [self updateSwatchViewWithColor:forColorView];
    //[showColor setNeedsDisplay];
}

//Touch parts : 

// Scales down the view and moves it to the new position. 
- (void)animateView:(UIImageView *)theView toPosition:(CGPoint) thePosition
{
	[UIView beginAnimations:nil context:NULL];
	[UIView setAnimationDuration:kAnimationDuration];
	// Set the center to the final postion
	theView.center = thePosition;
	// Set the transform back to the identity, thus undoing the previous scaling effect.
	theView.transform = CGAffineTransformIdentity;
	[UIView commitAnimations];	
}

-(void) dispatchTouchEvent:(CGPoint)position
{
	if (CGRectContainsPoint(colorMatrixFrame,position))
	{
		[self animateView:crossHairs toPosition: position];
		[self updateHueSatWithMovement:position];
		
	}
	else if (CGRectContainsPoint(gradientView.frame, position))
	{
		CGPoint newPos = CGPointMake(position.x,kBrightBarYCenter);
		[self animateView:brightnessBar toPosition: newPos];
		[self updateBrightnessWithMovement:position];
	}
	else
	{
	}
	
}


// Handles the start of a touch
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGPoint point = [[touches anyObject] locationInView:self];
    if (txtCurrent) {
        if (!CGRectContainsPoint(txtCurrent.frame, point)) {
            [txtCurrent resignFirstResponder];
        }
    }
	
	for (UITouch *touch in touches) {
		[self dispatchTouchEvent:[touch locationInView:self]];
		}	
}

// Handles the continuation of a touch.
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{  

	for (UITouch *touch in touches){
		[self dispatchTouchEvent:[touch locationInView:self]];
	}
	
}

- (void)drawRect:(CGRect)rect {
    
	//CGFloat x = currentHue * kMatrixWidth;
	//CGFloat y = currentSaturation * kMatrixHeight;
	
	//crossHairs.center = CGPointMake(x,y);
	
	//x = currentBrightness * gradientView.frame.size.width;
	
	//brightnessBar.center = CGPointMake(x,kBrightBarYCenter);
	
	[gradientView setupGradient];
	[gradientView setNeedsDisplay];
	//[self sendSubviewToBack:showColor];

}

- (UIColor *) getColorShown {
	return [UIColor colorWithHue:currentHue saturation:currentSaturation brightness:currentBrightness alpha:1.0];
}
- (BOOL)stringIsValid:(NSString *)string 
      forCharacterSet:(NSCharacterSet *)characters {
    BOOL isValid = YES;
    
    for (int counter = 0; counter < string.length; counter++) {
        unichar currentCharacter = [string characterAtIndex:counter];
        if ([characters characterIsMember:currentCharacter]) {
            // continue
        }
        else {
            isValid = NO;
            break;
        }
    }
    
    return isValid;
}
-(BOOL)isValidHexValue:(NSString *)hexValue {
    BOOL isValid = NO;
    
    NSString *trimmedString = 
    [hexValue stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    if (trimmedString.length == 6) {
        NSCharacterSet *hexadecimalCharacters = 
        [NSCharacterSet characterSetWithCharactersInString:@"0123456789ABCDEF"];
        if ([self stringIsValid:trimmedString
                forCharacterSet:hexadecimalCharacters]) {
            isValid = YES;
        }
    }
    
    return isValid;
}
-(void) textFieldDidBeginEditing:(UITextField *)textField
{
    txtCurrent = textField;
}
-(void) textFieldDidEndEditing:(UITextField *)textField
{
    if (textField.text.length==0) {
        [self setColor:currentColor];
    }
    else if(isTextChanged)
    {
        if(textField == txtHex)
        {
            if ([self isValidHexValue:textField.text]) {
                [self setColor:[UIColor colorWithHexString:textField.text]];
            }
            else [self setColor:currentColor];
        }
        else if (textField == txtR || textField == txtG || textField == txtB)
        {
            float R = textField==txtR?[txtR.text floatValue]/255.0f:currentColor.red;
            float G=  textField==txtG?[txtG.text floatValue]/255.0f:currentColor.green;
            float B=  textField==txtB?[txtB.text floatValue]/255.0f:currentColor.blue;
            [self setColor:[UIColor colorWithRed:R green:G blue:B alpha:1.0f]];
            
        }
        else if (textField == txtHue || textField == txtSat || textField == txtVal )
        {
            float hue=textField==txtHue?[txtHue.text floatValue]/360.0f:currentHue;
            float sat=textField==txtSat?[txtSat.text floatValue]/100.0f:currentSaturation;
            float bri=textField==txtVal?[txtVal.text floatValue]/100.0f:currentBrightness ;
            [self setColor:[UIColor colorWithHue:hue saturation:sat brightness:bri alpha:1.0f]];
        
        }
    }
    txtCurrent = nil;
    isTextChanged = NO;
}
-(BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    BOOL replace = YES;
    NSString *newText = [textField.text stringByReplacingCharactersInRange:range withString:string];
    if (textField==txtHex) {
        if (newText.length>6) {
            replace = NO;
        }
        else replace = [self stringIsValid:newText forCharacterSet:hexCharacterSet];
    }
    else if(newText.length>3)
        replace = NO;
    else if(![self stringIsValid:newText forCharacterSet:decimalCharacterSet])
        replace = NO;
    else
    {
        int integer = [newText intValue];
        if (textField==txtHue && integer>360) {
            replace = NO;
        }
        else if ((textField == txtSat || textField== txtVal) && integer >100)
            replace = NO;
        else if((textField == txtR || textField == txtG || textField == txtB) && integer>255)
            replace = NO;
    }
    if (replace) {
        isTextChanged = YES;
    }
    return replace;
}
-(BOOL) textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    return NO;
}
- (void)dealloc {
    [super dealloc];
	
}
-(BOOL) canBecomeFirstResponder
{
    return YES;
}
@end
